const path = require('path');
const {
  Menu, app, Tray, shell, nativeImage, BrowserWindow, ipcMain,
} = require('electron');
const setContextMenu = require('electron-context-menu');
const installRootCAFile = require('whistle/bin/ca');
const { version } = require('../package.json');
const {
  isEnabled, enableProxy, disableProxy, setEnabled, getTitle,
} = require('./proxy');
const { showMessageBox } = require('./dialog');
const {
  getJson, getString, requireW2, LOCALHOST, TRAY_ICON,
  sudoPrompt,
} = require('./util');
const { getOptions, sendMsg, getWin } = require('./context');
const { showWindow, restart } = require('./window');
const { showSettings, getSettings } = require('./settings');
const storage = require('./storage');
const cosDownloader = require('./cosDownloader');
const ProgressDialog = require('./progressDialog');



// 国际化支持
let currentLanguage = 'zh-CN';
let i18nData = {};

// 加载语言包
async function loadLanguagePack(lang = 'zh-CN') {
  try {
    const fs = require('fs');
    const i18nPath = path.join(__dirname, '../public/i18n', `${lang}.json`);
    if (fs.existsSync(i18nPath)) {
      const data = fs.readFileSync(i18nPath, 'utf8');
      i18nData = JSON.parse(data);
      currentLanguage = lang;
    }
  } catch (error) {
    console.warn(`Failed to load language pack: ${lang}`, error);
  }
}

// 获取翻译文本
function getText(key) {
  const keys = key.split('.');
  let value = i18nData;
  for (const k of keys) {
    if (value && typeof value === 'object' && k in value) {
      value = value[k];
    } else {
      return key; // 如果找不到翻译，返回key
    }
  }
  return value || key;
}

// 检测系统语言
function detectSystemLanguage() {
  const locale = app.getLocale();
  if (locale.startsWith('zh')) {
    return 'zh-CN';
  }
  return 'en-US';
}

// 从exe文件名中提取版本号
function extractVersionFromFileName(fileName) {
  // 匹配 whistle-client-v版本号.exe 的格式
  const versionMatch = fileName.match(/whistle-client-v(\d+\.\d+\.\d+)\.exe/);
  if (versionMatch) {
    return versionMatch[1];
  }
  return null;
}

// 从腾讯云获取最新的显示版本号
async function getDisplayVersionFromCOS() {
  try {
    const exeFiles = await cosDownloader.listExeFiles();
    if (exeFiles.length === 0) {
      return null;
    }
    
    // 找到最新版本
    const validVersions = exeFiles
      .map(fileName => extractVersionFromFileName(fileName))
      .filter(version => version !== null);
    
    if (validVersions.length === 0) {
      return null;
    }
    
    // 简单的版本号比较
    return validVersions.reduce((latest, current) => {
      const latestParts = latest.split('.').map(Number);
      const currentParts = current.split('.').map(Number);
      
      for (let i = 0; i < Math.max(latestParts.length, currentParts.length); i++) {
        const latestPart = latestParts[i] || 0;
        const currentPart = currentParts[i] || 0;
        
        if (currentPart > latestPart) {
          return current;
        } else if (currentPart < latestPart) {
          return latest;
        }
      }
      return latest;
    });
  } catch (error) {
    console.warn('Failed to get display version from COS:', error.message);
    return null;
  }
}

// 读取发布信息 (只获取最新的一条)
function getReleaseInfo(targetVersion) {
  try {
    const fs = require('fs');
    const releaseInfoPath = path.join(__dirname, '../release-info.json');
    
    if (!fs.existsSync(releaseInfoPath)) {
      return null;
    }
    
    const releaseData = JSON.parse(fs.readFileSync(releaseInfoPath, 'utf8'));
    
    // 获取最新的发布信息（数组中的第一条）
    if (releaseData.length > 0) {
      const latestRelease = releaseData[0];
      // 如果版本号匹配或者没有指定版本号，返回最新信息
      if (!targetVersion || latestRelease.version === targetVersion) {
        return latestRelease;
      }
    }
    
    return null;
  } catch (error) {
    console.warn('Failed to read release info:', error.message);
    return null;
  }
}



// 从腾讯云下载文件
async function downloadFromTencentCloud(version, downloadPath) {
  let progressDialog = null;
  
  try {
    console.log(`🚀 开始从腾讯云下载版本 ${version} 到路径: ${downloadPath}`);
    
    // 添加调试信息
    console.log(`🔍 调试信息 - 传入的下载路径: ${downloadPath}`);
    console.log(`🔍 调试信息 - 传入路径长度: ${downloadPath.length}`);
    
    // 确保下载目录存在
    const fs = require('fs');
    const childProcess = require('child_process');
    if (!fs.existsSync(downloadPath)) {
      console.log(`📁 创建下载目录: ${downloadPath}`);
      fs.mkdirSync(downloadPath, { recursive: true });
    }
    
    // 构造文件名（假设格式为 whistle-client-v版本号.exe）
    const fileName = `whistle-client-v${version}.exe`;
    
    // 检查路径长度，避免 Windows 路径长度限制
    const fullPath = path.join(downloadPath, fileName);
    console.log(`🔍 调试信息 - 完整文件路径: ${fullPath}`);
    console.log(`🔍 调试信息 - 完整路径长度: ${fullPath.length}`);
    
    if (fullPath.length > 240) { // 留一些余量
      throw new Error(`路径过长 (${fullPath.length} 字符)，请选择更短的下载路径。Windows 路径长度限制为 260 字符。`);
    }
    
    // 创建进度条对话框
    progressDialog = new ProgressDialog();
    progressDialog.show(`下载 ${fileName}`);
    
    // 调用cosDownloader来实际下载文件
    console.log('🚀 开始下载文件...');
    const downloadResult = await cosDownloader.downloadExeFile(fileName, downloadPath, (progress, downloaded, total, speed) => {
      // 更新进度条
      if (progressDialog) {
        progressDialog.updateProgress(progress, downloaded, total, speed);
      }
      
      // 控制台显示进度（保留原有日志）
      console.log(`下载进度: ${progress.toFixed(1)}% (${(downloaded / 1024 / 1024).toFixed(2)} MB / ${(total / 1024 / 1024).toFixed(2)} MB)`);
    });
    
    if (downloadResult.success) {
      // 关闭进度条
      if (progressDialog) {
        progressDialog.close();
        progressDialog = null;
      }
      
      console.log(`✅ 下载成功: ${downloadResult.localPath}`);
      console.log(`📁 文件大小: ${(downloadResult.fileSize / 1024 / 1024).toFixed(2)} MB`);
      console.log(`⏱️  下载用时: ${downloadResult.downloadTime}ms`);
      
      // 显示下载成功提示，询问是否立即安装
      const { dialog } = require('electron');
      // 获取当前安装路径用于提示
      const currentInstallPath = path.dirname(app.getPath('exe'));
      
      const installResult = await dialog.showMessageBox(getWin(), {
          type: 'info',
          title: '下载成功',
          message: '下载完成！是否立即开始覆盖安装？',
          buttons: ['立即覆盖安装', '稍后安装', '取消'],
          defaultId: 0, // 默认选中"立即覆盖安装"
          cancelId: 2   // 点击X或ESC时选择"取消"
        });
      
      if (installResult.response === 0) {
        // 用户选择立即安装（执行安装程序）
        console.log('🔍 调试信息 - 用户选择了立即安装');
        try {
          console.log(`🚀 开始执行安装程序: ${downloadResult.localPath}`);
          
          // 检查下载的文件是否存在和有效
          const fs = require('fs');
          if (!fs.existsSync(downloadResult.localPath)) {
            throw new Error(`下载的文件不存在: ${downloadResult.localPath}`);
          }
          
          // 检查文件大小（exe文件不应该太小）
          const fileStats = fs.statSync(downloadResult.localPath);
          if (fileStats.size < 1024 * 1024) { // 小于1MB可能有问题
            console.warn(`⚠️ 文件大小异常: ${fileStats.size} bytes`);
          }
          
          // 检查文件是否是exe格式
          if (!downloadResult.localPath.toLowerCase().endsWith('.exe')) {
            throw new Error(`下载的文件不是exe格式: ${downloadResult.localPath}`);
          }
          
          // 获取当前应用程序路径（旧版安装路径）
          const appPath = app.getPath('exe');
          const appDirectory = path.dirname(appPath);
          console.log(`当前应用程序路径: ${appPath}`);
          console.log(`📁 当前应用目录（旧版安装路径）: ${appDirectory}`);
          console.log(`📁 文件大小: ${(fileStats.size / 1024 / 1024).toFixed(2)} MB`);
          console.log(`📁 文件修改时间: ${fileStats.mtime}`);
          
                     // 直接启动安装程序，不显示进度条界面
           console.log('🚀 直接启动安装程序...');
          
          // 安装参数：优化安装体验，让用户看到安装过程
          const installArgs = [
            '/SILENT',               // 静默安装（显示进度条和安装界面）
            '/FORCECLOSEAPPLICATIONS', // 强制关闭应用程序
            '/RESTARTAPPLICATIONS',  // 重启应用程序
            '/DIR="' + appDirectory + '"'  // 指定安装目录，用引号包围路径
          ];
          
          console.log(`🚀 启动安装程序，参数: ${installArgs.join(' ')}`);
          console.log(`📁 安装目标路径: ${appDirectory}`);
          console.log(`🔍 调试信息 - 文件路径: ${downloadResult.localPath}`);
          console.log(`🔍 调试信息 - 文件是否存在: ${fs.existsSync(downloadResult.localPath)}`);
          console.log(`🔍 调试信息 - 文件大小: ${fs.statSync(downloadResult.localPath).size} bytes`);
          console.log(`🔍 调试信息 - 文件权限: ${fs.statSync(downloadResult.localPath).mode}`);
          
          // 按照正确的流程启动安装程序
          console.log('🚀 准备启动安装程序...');
          
          try {
            // 1. 启动安装程序 - 先触发 UAC 对话框
            console.log('🔍 启动安装程序，触发 UAC 对话框...');
            
            // 构造完整的安装命令
            const fullCommand = `"${downloadResult.localPath}" ${installArgs.join(' ')}`;
            console.log(`🔍 执行安装命令: ${fullCommand}`);
            
            // 使用 exec 直接执行，这会强制触发 Windows UAC 提示
            childProcess.exec(fullCommand, (error, stdout, stderr) => {
              if (error) {
                console.log(`⚠️ exec 执行错误: ${error.message}`);
                console.log(`🔍 错误代码: ${error.code}`);
              } else {
                console.log('✅ exec 执行成功');
              }
            });
            
            // 2. 等待用户确认 - 在 UAC 对话框中点击"是"
            console.log('⏳ 等待用户确认 UAC 对话框...');
            
                         // 3. 安装程序运行 - 安装程序开始安装
             console.log('✅ 安装程序启动请求已发送，应该会弹出 UAC 对话框');
             
             // 4. 应用自动关闭 - 安装程序会处理应用关闭
             console.log('🚀 安装程序已启动，等待安装完成...');
             console.log('✅ UAC 对话框应该已经弹出，请点击"是"允许安装程序运行');
             return; // 直接返回，让安装程序处理后续流程
            
          } catch (error) {
            console.error('❌ 启动安装程序失败:', error.message);
            
            // 显示错误信息并提供手动安装选项
            const errorResult = await dialog.showMessageBox(getWin(), {
              type: 'error',
              title: '启动安装程序失败',
              message: `无法启动安装程序，请尝试以下解决方案：\n\n1. 手动运行下载的安装程序\n2. 以管理员身份运行whistle\n3. 检查防病毒软件设置\n4. 重启电脑后重试\n\n错误详情：${error.message}`,
              buttons: ['打开下载目录', '手动运行安装程序', '取消'],
              defaultId: 0
            });
            
            if (errorResult.response === 0) {
              // 打开下载目录
              shell.openPath(path.dirname(downloadResult.localPath));
            } else if (errorResult.response === 1) {
              // 手动运行安装程序
              try {
                await shell.openPath(downloadResult.localPath);
                console.log('✅ 手动启动成功！');
              } catch (manualError) {
                console.log(`⚠️ 手动启动失败: ${manualError.message}`);
              }
            }
            return;
          }
          
        } catch (installError) {
          console.error('❌ 启动安装程序失败:', installError);
          console.error('❌ 错误类型:', installError.code);
          console.error('❌ 错误详情:', installError.stack);
          
                     // 安装程序启动失败
          
          // 根据错误类型提供不同的解决方案
          let errorMessage = `启动安装程序失败: ${installError.message}\n\n`;
          let suggestions = [];
          
          if (installError.code === 'ENOENT') {
            suggestions.push('• 检查下载的文件是否存在');
            suggestions.push('• 重新下载安装文件');
          } else if (installError.code === 'EACCES' || installError.code === 'EPERM') {
            suggestions.push('• 以管理员身份运行 Whistle');
            suggestions.push('• 右键点击 Whistle 选择“以管理员身份运行”');
          } else {
            suggestions.push('• 检查防病毒软件是否阻止了安装');
            suggestions.push('• 关闭其他安全软件后重试');
            suggestions.push('• 重启电脑后重试');
          }
          
          suggestions.push('• 手动运行下载的安装程序');
          
          errorMessage += '建议解决方案：\n' + suggestions.join('\n');
          
          const result = await dialog.showMessageBox(getWin(), {
            type: 'error',
            title: '安装程序启动失败',
            message: errorMessage,
            buttons: ['打开下载目录', '重新尝试', '取消'],
            defaultId: 0
          });
          
          if (result.response === 0) {
            // 打开下载目录
            shell.openPath(path.dirname(downloadResult.localPath));
          } else if (result.response === 1) {
            // 重新尝试 - 递归调用安装函数
            console.log('🔄 用户选择重新尝试安装');
            // 简单的重试逻辑，再次尝试shell.openPath
            try {
              await shell.openPath(downloadResult.localPath);
              await dialog.showMessageBox(getWin(), {
                type: 'info',
                title: '重新尝试',
                message: '已尝试重新启动安装程序，请检查是否成功。',
                buttons: ['确定']
              });
            } catch (retryError) {
              console.error('❌ 重新尝试也失败了:', retryError.message);
            }
          }
        }
      } else if (installResult.response === 1) {
        // 用户选择稍后安装，询问是否打开下载目录
        const openFolder = await dialog.showMessageBox(getWin(), {
          type: 'question',
          title: '打开下载目录',
          message: '是否打开下载目录查看文件？',
          buttons: ['打开目录', '取消']
        });
        
        if (openFolder.response === 0) {
          // 打开下载目录
          shell.openPath(downloadPath);
        }
      }
      // installResult.response === 2 是关闭，不需要任何操作
      
    } else {
      // 关闭进度条
      if (progressDialog) {
        progressDialog.close();
        progressDialog = null;
      }
      
      console.error('❌ 下载失败:', downloadResult.error);
      const { dialog } = require('electron');
      await dialog.showMessageBox(getWin(), {
        type: 'error',
        title: '下载错误',
        message: `下载失败: ${downloadResult.error}`,
        buttons: ['确定']
      });
    }
    
  } catch (error) {
    // 关闭进度条
    if (progressDialog) {
      progressDialog.close();
      progressDialog = null;
    }
    
    console.error('❌ 下载过程中发生错误:', error);
    const { dialog } = require('electron');
    
    let errorMessage = error.message;
    if (error.message.includes('ENOENT')) {
      errorMessage = `下载失败：无法创建文件或目录。\n\n可能的原因：\n1. 路径过长（Windows 限制 260 字符）\n2. 没有写入权限\n3. 磁盘空间不足\n\n建议：\n1. 选择更短的下载路径\n2. 确保有写入权限\n3. 检查磁盘空间\n\n详细错误：${error.message}`;
    }
    
    await dialog.showMessageBox(getWin(), {
      type: 'error',
      title: '下载错误',
      message: errorMessage,
      buttons: ['确定']
    });
  }
}

const { getServerProxy } = requireW2('set-global-proxy');

let isSettingProxy;
const INTERVAL = 5000;
const REPO_URL = 'https://gitee.com/dasnn/whistle';
let tray; // 防止被 GC https://github.com/amhoho/electron-cn-docs/blob/master/faq.md
const ICON_SIZE = { width: 15 };
const showRepo = () => {
  shell.openExternal(REPO_URL);
};
const EDIT_MENU = {
  label: getText('menu.edit'),
  submenu: [
    {
      label: getText('menu.undo'),
      accelerator: 'CmdOrCtrl+Z',
      role: 'undo',
    },
    {
      label: getText('menu.redo'),
      accelerator: 'Shift+CmdOrCtrl+Z',
      role: 'redo',
    },
    {
      type: 'separator',
    },
    {
      label: getText('menu.cut'),
      accelerator: 'CmdOrCtrl+X',
      role: 'cut',
    },
    {
      label: getText('menu.copy'),
      accelerator: 'CmdOrCtrl+C',
      role: 'copy',
    },
    {
      label: getText('menu.paste'),
      accelerator: 'CmdOrCtrl+V',
      role: 'paste',
    },
    {
      label: getText('menu.selectAll'),
      accelerator: 'CmdOrCtrl+A',
      role: 'selectall',
    },
    { type: 'separator' },
    {
      label: getText('menu.help'),
      click: showRepo,
    },
  ],
};

setContextMenu({
  showSelectAll: true,
  showSaveImageAs: true,
  showLookUpSelection: false,
  showSearchWithGoogle: false,
  showLearnSpelling: false,
  showCopyLink: false,
  showInspectElement: false,
});
Menu.setApplicationMenu(Menu.buildFromTemplate([
  {
    label: app.getName(),
    submenu: [
      {
        label: 'Quit',
        accelerator: 'CmdOrCtrl+Q',
        role: 'quit',
      },
    ],
  },
  EDIT_MENU,
]));

const getIcon = (iconPath) => nativeImage.createFromPath(iconPath).resize(ICON_SIZE);

let curTitle;
const updateTitle = () => {
  const title = getTitle();
  if (title === curTitle) {
    return;
  }
  curTitle = title;
  const win = getWin();
  if (win) {
    win.setTitle(curTitle);
  }
  if (tray) {
    tray.setToolTip(curTitle);
  }
};

const setStartAtLogin = (startAtLogin) => {
  if (!app.isPackaged) {
    return;
  }
  startAtLogin = !!startAtLogin;
  try {
    app.setLoginItemSettings({ openAtLogin: startAtLogin });
  } catch (e) {}
};

module.exports = async () => {
  // 初始化语言包
  const systemLang = detectSystemLanguage();
  await loadLanguagePack(systemLang);
  
  const UNCHECK_ICON = getIcon(path.join(__dirname, '../public/uncheck.png'));
  const CHECKED_ICON = getIcon(path.join(__dirname, '../public/checked.png'));
  const updateCheckbox = (menu, trayMenu, checked) => {
    const icon = checked ? CHECKED_ICON : UNCHECK_ICON;
    menu.icon = icon;
    trayMenu.icon = icon;
    Menu.setApplicationMenu(Menu.buildFromTemplate(menus)); // eslint-disable-line
    tray.setContextMenu(Menu.buildFromTemplate(trayMenus)); // eslint-disable-line
  };
  const updateProxyStatus = () => {
    updateCheckbox(proxyMenu, proxyTrayMenu, isEnabled()); // eslint-disable-line
    storage.setProperty('autoSetProxy', isEnabled());
  };
  const enableSystemProxy = async () => {
    isSettingProxy = true;
    try {
      await enableProxy(getSettings());
      updateProxyStatus();
    } catch (e) {}
    isSettingProxy = false;
    updateTitle();
  };

  const disableSystemProxy = async () => {
    try {
      await disableProxy();
      updateProxyStatus();
    } catch (e) {}
    updateTitle();
  };

  const switchSystemProxy = () => {
    if (isEnabled()) {
      disableSystemProxy();
    } else {
      enableSystemProxy();
    }
  };

  const updateStartAtLogin = (startAtLogin) => {
    startAtLogin = !!startAtLogin;
    setStartAtLogin(startAtLogin);
    updateCheckbox(startMenu, startTrayMenu, startAtLogin); // eslint-disable-line
    storage.setProperty('startAtLogin', startAtLogin);
  };

  const switchStartAtLogin = () => {
    updateStartAtLogin(!storage.getProperty('startAtLogin'));
  };

  const installRootCA = async () => {
    try {
      const useExceFunc = await installRootCAFile(getOptions().rootCAFile, (cmd) => {
        sudoPrompt(cmd, (err) => {
          if (!err) {
            sendMsg({ type: 'enableCapture' });
          }
        });
      });
      if (!useExceFunc) {
        sendMsg({ type: 'enableCapture' });
      }
    } catch (e) {}
  };

  let checking;
  const checkUpdate = async () => {
    if (checking) {
      return;
    }
    checking = true;
    try {
      // 从Gitee获取版本号进行比较
      const pkg = await getJson('https://gitee.com/dasnn/whistle/raw/main/package.json');
      const giteeVersion = getString(pkg && pkg.version);
      if (!giteeVersion) {
        return showMessageBox(getText('messages.networkError'), checkUpdate);
      }
      
      // 从腾讯云获取显示版本号
      const displayVersion = await getDisplayVersionFromCOS();
      
      // 使用Gitee版本号进行比较
      if (version === giteeVersion) {
        return showMessageBox(getText('messages.upToDate'), {
          title: '',
          type: 'info',
        });
      }
      
      // 显示更新提示时使用腾讯云的版本号（如果可用）
      const versionToShow = displayVersion || giteeVersion;
      
      // 获取发布信息
      const releaseInfo = getReleaseInfo(versionToShow);
      
             // 构建更新信息消息 - 优化排版和布局
       let updateMessage = `🎉 发现新版本可用！\n\n`;
       updateMessage += `✨ 升级到最新版本，享受更稳定、更流畅的使用体验\n\n`;
       
       if (releaseInfo) {
         updateMessage += `📋 版本信息\n`;
         updateMessage += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
         updateMessage += `🔹 最新版本：${versionToShow}\n`;
         updateMessage += `🔹 当前版本：${version}\n`;
         updateMessage += `🔹 更新标题：${releaseInfo.title}\n`;
         if (releaseInfo.date) {
           updateMessage += `🔹 发布日期：${releaseInfo.date}\n`;
         }
       } else {
         updateMessage += `📋 版本信息\n`;
         updateMessage += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
         updateMessage += `🔹 最新版本：${versionToShow}\n`;
         updateMessage += `🔹 当前版本：${version}\n`;
       }
      
      try {
        const { dialog } = require('electron');
        
        // 第一步：显示更新信息和立即覆盖安装按钮
        const updateInfoResult = await dialog.showMessageBox(getWin(), {
          type: 'info',
          title: '发现新版本-升级程序',
          message: updateMessage,
          buttons: ['立即升级', getText('messages.viewUpdateGuide'), '取消'],
          defaultId: 0,
          cancelId: 2
        });
        
                  if (updateInfoResult.response === 0) {
          // 用户点击了"立即覆盖安装" - 进入第二步：选择下载方式
          const os = require('os');
          const defaultPath = path.join(os.homedir(), 'Downloads');
          
          // 获取当前安装路径用于提示
          const currentAppPath = app.getPath('exe');
          const currentAppDirectory = path.dirname(currentAppPath);
          
          const downloadResult = await dialog.showMessageBox(getWin(), {
            type: 'question',
            title: '选择下载方式',
            message: `请选择下载方式：`,
            buttons: [`下载到默认路径\n(${defaultPath})`, '选择下载路径', '取消'],
            defaultId: 0,
            cancelId: 2
          });
          
          if (downloadResult.response === 0) {
            // 用户点击了"下载到默认路径"
            console.log(`🚀 用户选择默认路径下载: ${defaultPath}`);
            await downloadFromTencentCloud(versionToShow, defaultPath);
          } else if (downloadResult.response === 1) {
            // 用户点击了"选择下载路径" - 直接弹出文件夹选择器
            console.log(`🚀 用户选择自定义路径下载`);
            const folderResult = await dialog.showOpenDialog(getWin(), {
              properties: ['openDirectory'],
              title: '选择下载文件夹',
              defaultPath: require('os').homedir()
            });
            
            if (!folderResult.canceled && folderResult.filePaths.length > 0) {
              const selectedPath = folderResult.filePaths[0];
              console.log(`🔍 用户选择路径: ${selectedPath}`);
              await downloadFromTencentCloud(versionToShow, selectedPath);
            } else {
              console.log('🔍 用户取消选择文件夹');
            }
          }
          // downloadResult.response === 2 是 取消，不需要处理
          
        } else if (updateInfoResult.response === 1) {
          // 用户点击了"查看更新指南"
          console.log(`🔍 用户查看更新指南`);
          showRepo();
        }
        // updateInfoResult.response === 2 是 取消，不需要处理
      } catch (error) {
        console.error('显示更新对话框时出错:', error);
        showMessageBox(`显示更新对话框时出错: ${error.message}`, {
          type: 'error',
          title: '错误'
        });
      }
    } catch (e) {
      showMessageBox(e, checkUpdate);
    } finally {
      checking = false;
    }
  };
  const proxyMenu = {
    label: getText('menu.setAsSystemProxy'),
    icon: UNCHECK_ICON,
    accelerator: 'CmdOrCtrl+R',
    click: switchSystemProxy,
  };
  const startMenu = {
    label: getText('menu.startAtLogin'),
    icon: UNCHECK_ICON,
    click: switchStartAtLogin,
  };
  const menus = [
    {
      label: app.getName(),
      submenu: [
        {
          label: getText('menu.proxySettings'),
          accelerator: 'CommandOrControl+,',
          click: showSettings,
        },
        {
          label: getText('menu.installRootCA'),
          click: installRootCA,
        },
        {
          label: getText('menu.checkUpdate'),
          click: checkUpdate,
        },
        { type: 'separator' },
        proxyMenu,
        { type: 'separator' },
        startMenu,
        { type: 'separator' },
        {
          label: getText('menu.restart'),
          accelerator: 'CommandOrControl+Shift+R',
          click: restart,
        },
        {
          label: getText('menu.quit'),
          accelerator: 'CmdOrCtrl+Q',
          click: () => app.quit(),
        },
      ],
    },
    EDIT_MENU,
  ];
  const proxyTrayMenu = {
    label: getText('menu.setAsSystemProxy'),
    icon: UNCHECK_ICON,
    click: switchSystemProxy,
  };
  const startTrayMenu = {
    label: getText('menu.startAtLogin'),
    icon: UNCHECK_ICON,
    click: switchStartAtLogin,
  };
  const trayMenus = [
    {
      label: getText('menu.hideAllWindows'),
      click() {
        try {
          BrowserWindow.getAllWindows().forEach(win => win.hide());
        } catch (e) {}
      },
    },
    { type: 'separator' },
    proxyTrayMenu,
    { type: 'separator' },
    startTrayMenu,
    { type: 'separator' },
    {
      label: getText('menu.quit'),
      role: 'quit',
    },
  ];
  const trayIcon = getIcon(TRAY_ICON);
  trayIcon.setTemplateImage(true);
  tray = new Tray(trayIcon);
  tray.on('click', showWindow);
  updateStartAtLogin(storage.getProperty('startAtLogin'));

  let autoSet = storage.getProperty('autoSetProxy');
  if (autoSet) {
    await enableSystemProxy();
  } else {
    setEnabled(false);
  }
  updateTitle();
  const detectProxy = () => {
    if (isSettingProxy || !isEnabled()) {
      autoSet = false;
      updateTitle();
      return setTimeout(detectProxy, INTERVAL);
    }
    getServerProxy(async (_, proxy) => {
      if (!isSettingProxy && proxy) {
        const settings = getSettings();
        const { http, https } = proxy;
        const { port } = settings;
        const host = settings.host || LOCALHOST;
        if (!http.enabled || !https.enabled || http.host !== host
          || https.host !== host || http.port !== port || https.port !== port) {
          if (autoSet) {
            await enableSystemProxy();
          } else {
            setEnabled(false);
            updateProxyStatus();
          }
        } else {
          autoSet = false;
        }
      } else if (autoSet) {
        await enableSystemProxy();
      }
      updateTitle();
      setTimeout(detectProxy, INTERVAL);
    });
  };
  setTimeout(detectProxy, autoSet ? 200 : INTERVAL);
};